<?php
/**
 * @version SVN: $Id: languagehelper.php 1221 2010-05-31 19:00:50Z elkuku $
 * @package    EasyCreator
 * @subpackage Helpers
 * @author     EasyJoomla {@link http://www.easy-joomla.org Easy-Joomla.org}
 * @author     Nikolai Plath {@link http://www.nik-it.de}
 * @author     Created on 10-Oct-2009
 * @license    GNU/GPL, see JROOT/LICENSE.php
 */

//-- No direct access
defined('_JEXEC') or die('=;)');

class EasyLanguageHelper
{
	public static function discoverLanguages(EasyProject $project)
	{
	    static $languages = array();

	    $pKey = $project->type.$project->scope.$project->comName;

	    if(isset($languages[$pKey]))
	    {
	        return $languages[$pKey];
	    }

	    $langs = JFactory::getLanguage()->getKnownLanguages();

	    if(count($langs > 1))
	    {
	        //-- We have more than one language.. order en-GB at first position
	        $enGB = array('en-GB'=>$langs['en-GB']);
	        unset($langs['en-GB']);
	        $langs = $enGB + $langs;
	    }

	    $languages[$pKey] = array();

	    $paths = $project->getLanguagePaths();

	    if( ! $paths) return array();

	    foreach ($langs as $tag => $lang)
	    {
    	    foreach ($paths as $scope => $path)
    	    {
    	    	$dir = $path.DS.'language'.DS.$tag;

    	    	$fileName = $project->getLanguageFileName($scope);

    	    	if(JFile::exists($dir.DS.$tag.'.'.$fileName))
    	    	{
    	    	    $languages[$pKey][$tag][] = $scope;
    	    	}
    	    }//foreach
	    }//foreach

	    return $languages[$pKey];
	}//function

	public static function checkFile(EasyProject $project, $lang, $scope)
	{
	    ecrLoadHelper('language');
	    $subPath = 'language'.DS.$lang;
        $fileName = EasyLanguage::getFileName($lang, $scope, $project, false);

        //-- Get component parameters
        $params = JComponentHelper::getParams('com_easycreator');

        $file = new stdClass();

        $file->fileName = $fileName;
        $file->lang = $lang;
        $file->scope = $scope;
        $file->exists =(JFile::exists($fileName)) ? true : false;
        $file->isUFT8 = false;
        $file->hasBOM = false;

        if($file->exists)
        {
            //--Check if file is UTF-8 encoded
            $file->isUFT8 =
                $params->get('langfiles_chk_utf8') ?
                self::is_utf8(JFile::read($fileName))
                : 'NOT CHECKED';

            //--Detect BOM
            $file->hasBOM =
                $params->get('langfiles_chk_bom') ?
                self::detectBOM_utf8($fileName)
                : 'NOT CHECKED';
        }

        self::displayResults($file);
	}//function

	/**
     * @param JObject $file a file object
     */
    public static function displayResults($file)
    {
        //--Check if file exists
        if($file->exists)
        {
            echo '<span class="img icon-16-check_ok" />'.JText::_('Found');
        }
        else
        {
            echo '<span class="img icon-16-check_fail" />'.JText::_('Not found');
            ecrHTML::drawButtonCreateLanguageFile($file->lang, $file->scope);

            return;
        }

        //--Check if file is UTF-8 encoded
        if($file->isUFT8)
        {
            if($file->isUFT8 == 'NOT CHECKED')
            {
                echo '<span class="img icon-16-yellowled" />';
                echo '<span class="hasEasyTip" title="'.JText::_('Not checked for UFT8').'" style="color: orange;">';
                echo JText::_('UTF-8').'</span>';
            }
            else
            {
                echo '<span class="img icon-16-check_ok" />'.JText::_('UTF-8');
            }
        }
        else
        {
            ecrHTML::displayMessage(array(JText::_('File is not UTF-8 encoded'), $fileName), 'error');
        }

        //--Detect BOM
        if($file->hasBOM)
        {
            if($file->hasBOM == 'NOT CHECKED')
            {
                echo '<span class="img icon-16-yellowled" />';
                echo '<span class="hasEasyTip" title="'.JText::_('Not checked for BOM').'" style="color: orange;">';
                echo JText::_('BOM').'</span>';
            }
            else
            {
                ecrHTML::drawButtonRemoveBOM($file->fileName);
            }
        }
        else
        {
            echo '<span class="img icon-16-check_ok" />'.JText::_('No BOM');
        }
    }//function

    /**
     * Simple UTF-8-ness checker using a regular expression created by the W3C:
     * php-note-2005 at ryandesign dot com
     *
     * @param string $string
     *
     * @return bool true if $string is valid UTF-8
     */
    private function is_utf8($string)
    {
        $test =(is_array($string)) ? implode("\n", $string) : $string;

        //-- Using only the first 1000 characters.
        //-- strange error happens sometimes leading to server collapse :( @todo: investigate...
        $test = substr($test, 0, 100);

        return preg_match('%^(?:
              [\x09\x0A\x0D\x20-\x7E]            # ASCII
            | [\xC2-\xDF][\x80-\xBF]             # non-overlong 2-byte
            |  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
            | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
            |  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
            |  \xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
            | [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
            |  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
        )*$%xs', $test);

    }//function

    /**
     * Searches for a UTF-8 BOM/Signature in a given file.
     *
     * PHP Function to remove UTF-8 BOM/Signature from the beginning of a file.
     * @author http://develobert.blogspot.com/
     *
     * @param $file string filename
     *
     * @return bool true if a BOM is detected
     */
    public function detectBOM_utf8($filename)
    {
        $size = filesize($filename);

        if($size < 3)
        {
            // BOM not possible
            return false;
        }

        if($fh = fopen($filename, 'r+b'))
        {
            $test = bin2hex(fread($fh, 3));

            if(trim($test) == 'efbbbf')
            {
                if($size == 3 && ftruncate($fh, 0))
                {
                    // Empty other than BOM
                    fclose($fh);
                    return false;
                }
                else
                {
                    //---------------
                    //-- BOM found --
                    //---------------
                    fclose($fh);

                    return true;
                }
            }
            else
            {
                // No BOM found
                fclose($fh);
                return false;
            }
        }
        else
        {
            echo 'unable to open file '.$filename.'<br />';
            return false;
        }
    }//function

   /**
     * Searches for a UTF-8 BOM/Signature in a given file and removes it.
     *
     * @author:   http://develobert.blogspot.com/
     *
     * @param $file string filename
     *
     * @return bool true if a BOM is detected and removed
     */
    public function removeBOM_utf8($filename)
    {
        $filename = JPATH_ROOT.$filename;
        $size = filesize($filename);

        if( $size < 3 )
        {
            //-- BOM not possible
            return true;
        }

        if($fh = fopen($filename, 'r+b'))
        {
            if(bin2hex(fread($fh, 3)) == 'efbbbf')
            {
                if($size == 3 && ftruncate($fh, 0))
                {
                    //-- Empty other than BOM
                    fclose($fh);
                    return true;
                }
                else if($buffer = fread($fh, $size))
                {
                    //-- BOM found
                    //-- Shift file contents to beginning of file
                    if(ftruncate($fh, strlen($buffer)) && rewind($fh))
                    {
                        if(fwrite($fh, $buffer))
                        {
                            fclose($fh);
                            return true;
                        }
                    }
                }
            }
            else
            {
                //-- No BOM found
                fclose($fh);
                return true;
            }
        }
        else
        {
            echo 'unable to open file '.$filename.'<br />';
            return false;
        }
    }//function

}//class
